﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Spinning.Spinning.Unitity;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Phone.Info;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using com.google.zxing.qrcode;
using Microsoft.Devices;
using com.google.zxing.common;
using com.google.zxing;
using System.Net;

namespace Spinning.Spinning.Entity.Scenes
{
    class ConnectScene : Scene
    {
        TextEntity te;
        QRSprite QR;
        Sprite readerSprite;
        bool isHost;

        //Reader
        private DispatcherTimer _timer;
        private ObservableCollection<string> _matches;

        private PhotoCameraLuminanceSource _luminance;
        private QRCodeReader _reader;
        private PhotoCamera _photoCamera;
        System.Windows.Media.VideoBrush _previewVideo;
        //End of Reader
        
        //UDP
        private UdpAnySourceMulticastChannel Channel { get; set; }
        //

        public ConnectScene()
            : base()
        {
            Size = new Vector2(1);
        }

        public override void OnLoad()
        {
            base.OnLoad();
            Sprite backGroundSprite = new Sprite();
            backGroundSprite.textureName = "bg";
            backGroundSprite.ZIndex = Constants.background;
            backGroundSprite.OnLoad();
            this.Attach(backGroundSprite);

            ButtonSprite writeQRSprite = new ButtonSprite();
            writeQRSprite.textureName = "p1/play";
            writeQRSprite.ZIndex = Constants.ui;
            writeQRSprite.Position = new Vector2(40, 680);
            writeQRSprite.OnLoad();
            TouchManager.RegisteTouchArea(writeQRSprite);
            this.Attach(writeQRSprite);

            ButtonSprite readQRSprite = new ButtonSprite();
            readQRSprite.textureName = "p1/versus";
            readQRSprite.ZIndex = Constants.ui;
            readQRSprite.Position = new Vector2(240, 680);
            readQRSprite.OnLoad();
            TouchManager.RegisteTouchArea(readQRSprite);
            this.Attach(readQRSprite);

            // QRcode
            int QRsize = 400;
            QR = new QRSprite("Spinning Connect!," + Game1.GetDeviceUniqueID() + ",", new Point(QRsize, QRsize));
            QR.Position = new Vector2(240 - QRsize / 2, 300 - QRsize / 2);
            QR.ZIndex = Constants.ui;
            QR.Alpha = 0;
            this.Attach(QR);
            //

            // readerImage
            readerSprite = new Sprite();
            readerSprite.textureName = "teachWater/start";
            readerSprite.ZIndex = Constants.ui;
            readerSprite.Position = new Vector2(0, 300);
            readerSprite.OnLoad();
            readerSprite.Alpha = 0;
            this.Attach(readerSprite);

            //

            te = new TextEntity();
            ResourceManager.ContentRoot = "";
            te.fontString = "TestFont";
            te.OnLoad();
            te.Origin = new Vector2(0.5f);
            te.Position = new Vector2(200, 50);
            te.Color = Color.Blue;
            //te.Alpha = 0;
            te.ZIndex = Constants.debugText;
            Attach(te);

            writeQRSprite.OnTouchEvent += OnWriteTouch;
            readQRSprite.OnTouchEvent += OnReadTouch;
            ReaderInit();

            //UDP
            this.Channel = new UdpAnySourceMulticastChannel(IPAddress.Parse("224.0.1.100"), 3000);
            this.Channel.AfterOpen += new EventHandler(Channel_AfterOpen);
            this.Channel.BeforeClose += new EventHandler(Channel_BeforeClose);
            this.Channel.PacketReceived += new EventHandler<UdpPacketReceivedEventArgs>(Channel_PacketReceived);

            this.Channel.Open();
            //
        }

        void ReaderInit() 
        {
            _matches = new ObservableCollection<string>();

            
            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMilliseconds(250);
            _timer.Tick += (o, arg) => ScanPreviewBuffer();
            
            _photoCamera = new PhotoCamera();
            _photoCamera.Initialized += OnPhotoCameraInitialized;
            
            _previewVideo = new System.Windows.Media.VideoBrush();

            _previewVideo.SetSource(_photoCamera);

            CameraButtons.ShutterKeyHalfPressed += (o, arg) => _photoCamera.Focus();


        }

        void OnWriteTouch(BaseEntity entity, TouchLocation touchLocation)
        {
            if (readerSprite.Alpha == 1) { }  // disable QR writer butten
            else
            {
                if (QR.Alpha == 0)
                {
                    isHost = false;
                    Game1.clientId = Game1.GetDeviceUniqueID();
                    //this.Channel.Open();
                }
                else
                {
                    Game1.clientId = "";
                    //this.Channel.Close();
                }
                QR.Alpha = -QR.Alpha + 1;
                te.Value = "CLIENT";
            }
        }

        void OnReadTouch(BaseEntity entity, TouchLocation touchLocation)
        {
            if (QR.Alpha == 1) { }  // disable QR reader butten
            else
            {
                if (readerSprite.Alpha == 0)
                {
                    isHost = true;
                    _timer.Start();
                }
                else
                {
                    _timer.Stop();
                }
                readerSprite.Alpha = -readerSprite.Alpha + 1;
                te.Value = "HOST";
            }
        }

        private void OnPhotoCameraInitialized(object sender, CameraOperationCompletedEventArgs e)
        {
            int width = Convert.ToInt32(_photoCamera.PreviewResolution.Width);
            int height = Convert.ToInt32(_photoCamera.PreviewResolution.Height);

            _luminance = new PhotoCameraLuminanceSource(width, height);
            _reader = new QRCodeReader();
        }

        private void ScanPreviewBuffer()
        {
            try
            {
                _photoCamera.GetPreviewBufferY(_luminance.PreviewBufferY);
                var binarizer = new HybridBinarizer(_luminance);
                var binBitmap = new BinaryBitmap(binarizer);
                var result = _reader.decode(binBitmap);
                _previewVideo.Dispatcher.BeginInvoke(() => DisplayResult(result.Text));
            }
            catch
            {
            }
        }

        private void DisplayResult(string text)
        {
            if (!_matches.Contains(text))
                _matches.Add(text);
            te.Value = text;

            string[] temp;

            temp = text.Split(',');

            if (temp[0] == "Spinning Connect!")  //你是Host
            {
                onSuccessReadEnemyInfo(temp[1]);
                //GoToHostScene();
            }
        }

        void onSuccessReadEnemyInfo(String clientId)
        {
            //te.Value = clientId;
            Game1.clientId = clientId;

            this.Channel.Send("hostId:{0},clientId:{1},isHost:{2},", Game1.hostId, clientId, isHost);
            
            stopCamera();
            //GoToScene();
        }

        void stopCamera()
        {
            //dispose PhotoCamera
            if (_photoCamera != null)
                _photoCamera.Dispose();
            _photoCamera = null;
        }

        void GoToClientScene()
        {
            Game1.stageManager.GoToScene("client");
        }

        void GoToHostScene()
        {
            Game1.stageManager.GoToScene("host");
        }

        void Channel_PacketReceived(object sender, UdpPacketReceivedEventArgs e)
        {
            //if(e.Message.Length!=0)
            //te.Value = e.Message;

            string[] temp;
            string[] temp1;

            temp = e.Message.Split(',');

            NoKeyFoundDictionary dataDictionary = new NoKeyFoundDictionary();

            bool partyFlag = false;

            for (int i = 0; i < temp.Length; i++)
            {
                temp1 = temp[i].Split(':');
                if(temp1.Length>=2)
                dataDictionary.Add(temp1[0], temp1[1]);
            }

            

            if (dataDictionary.Get("hostId") == Game1.hostId && dataDictionary.Get("clientId") == Game1.clientId)
            {
                partyFlag = true;
                if (dataDictionary.Get("clientAns") == "true" && dataDictionary.Get("isHost")=="False")
                {
                    if (isHost)
                    {
                        //te.Value += "GoToHostScene()";
                        GoToHostScene();
                    }
                }
            }
            else if (dataDictionary.Get("clientId") == Game1.clientId && dataDictionary.Get("hostId")!="noKey")   // client 知道host是誰
            {
                Game1.hostId = dataDictionary.Get("hostId");
                partyFlag = true;
                this.Channel.Send("clientAns:true,hostId:{0},clientId:{1},isHost:{2},", Game1.hostId, Game1.clientId, isHost);
                //te.Value = "GoToClientScene()";
                GoToClientScene();
            }
            else
            {
                partyFlag = false;
            }

            if (partyFlag) 
            {

            }


            //if (temp[0] == "END")
            //{
            //    return;
            //}

            //if (temp.Length >= 3 && temp[0] == Game1.myId)
            //{
            //    return;
            //}

            //if (temp.Length == 3 && temp[1] == Game1.myId) //敵人送出你的ID 要求配對 (你是使用QR的 你是client
            //{
            //    Game1.enemyId = temp[0];
            //    te.Value = Game1.enemyId;
            //    this.Channel.Send("Accept Connect!,{0},{1},", Game1.myId, Game1.enemyId);
            //    GoToClientScene();
            //}

            //if (temp.Length == 4 && temp[1] == Game1.enemyId && temp[2] == Game1.myId&&temp[0] =="Accept Connect!") //你是host
            //{
            //    GoToHostScene();
            //}
        }

        void Channel_BeforeClose(object sender, EventArgs e)
        {
            this.Channel.Send("END,{0}, leaves the UDP Multicast chat,", Game1.hostId);
        }

        void Channel_AfterOpen(object sender, EventArgs e)
        {
            this.Channel.Send("BEGIN,{0}, enters the UDP Multicast chat,", Game1.hostId);
        }

        public override Scene Clone()
        {
            Scene scene = new ConnectScene();
            scene.Size = new Vector2(Constants.Window_Width, Constants.Window_Height);
            scene.OnLoad();
            scene.SortChildren();
            return scene;
        }
    }
}
